-
Notifications
You must be signed in to change notification settings - Fork 2
/
_findnext.c
179 lines (143 loc) · 6.29 KB
/
_findnext.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/*++
toro C Library
https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library
Copyright (c) 2017-2024, Kilian Kegel. All rights reserved.
SPDX-License-Identifier: GNU General Public License v3.0
Module Name:
_findnext.c
Abstract:
Microsoft C Library specific function _findnext()
TODO: 1. int _findnext64i32(intptr_t handle,struct _finddata64i32_t *fileinfo);
2. set errno -> https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/findnext-functions?view=msvc-160#return-value
3. set errno
EINVAL Invalid parameter : fileinfo was NULL.Or, the operating system returned an unexpected error.
ENOENT No more matching files could be found.
ENOMEM Not enough memory or the file name's length exceeded MAX_PATH.
Author:
Kilian Kegel
--*/
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <io.h>
#include <cde.h>
//
#include <CdeServices.h>
#include "__cdeFindFirst.h"
#define _A_CDE_EXTENSION_DONE 0x80 // DONE FLAG -- File attribute constants extension from IO.H
extern char* __cdeSplitSearchNameExt2Upcase(const char* pstr, char** ppStrFULL, char** ppStrEXT);
extern char* __cdeStrMatch(const char* pStr, const size_t lenName, const char* pPat);
/** _findnext()
*
Synopsis
#include <io.h>
int _findnext64i32(intptr_t handle,struct _finddata64i32_t *fileinfo);
Description
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/findnext-functions?view=msvc-160
Paramters
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/findnext-functions?view=msvc-160#parameters
Returns
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/findnext-functions?view=msvc-160#return-value
**/
int _findnext64i32(intptr_t hFile, struct _finddata64i32_t* pFindData)
{
int nRet = -1; //assume error
CDEFINDFIRSTNEXT* pcdeFindFirstNextData = (CDEFINDFIRSTNEXT*)hFile;
CDEFILEINFO* pCdeFileInfo;
size_t lenName = (size_t)-1LL;
bool fPatEXTLess = NULL == pcdeFindFirstNextData->pstrSearchPatEXT; // search pattern EXT less
bool fFilEXTLess = false; // file pattern EXT less
do {
for (
/* clause-1 */
pCdeFileInfo = pcdeFindFirstNextData->pCdeFileInfo
; /* expression-2 */
-1LL != pCdeFileInfo->time_write
; /* expression-3 */
pCdeFileInfo->attrib |= _A_CDE_EXTENSION_DONE /* mark entry done */,
pCdeFileInfo = (void*)((char*)&pCdeFileInfo[0] /* update to next entry */
+ sizeof(CDEFILEINFO)
+ strlen(pCdeFileInfo->strFileName)
+ sizeof((char)'\0'))
)
{
if (_A_CDE_EXTENSION_DONE & pCdeFileInfo->attrib)
continue;
//
// check if there is ".EXT", that means file forename length is != 0xFFFFFFFF (UINT64_MAX)
//
if (1)
{
/*
files:
"file w/o ext"
excluded temporarily: "."
excluded temporarily: ".."
matching EXT pattern:
NULL == pcdeFindFirstNextData->pstrSearchPatEXT
"*" == pcdeFindFirstNextData->pstrSearchPatEXT
"?" == pcdeFindFirstNextData->pstrSearchPatEXT
COMMAND LINE RESULTS IN
EXTless only "*." SearchPatNAM: "*" SearchPatEXT: "(null)"
EXTless + matching EXT "*.?" SearchPatNAM: "*" SearchPatEXT: "?"
EXTless + matching EXT "*.*" SearchPatNAM: "*" SearchPatEXT: "*"
*/
//
// detect length of strFileName until ".EXT"
//
if (strlen(pCdeFileInfo->strFileName) != strspn(pCdeFileInfo->strFileName, ".")) // skip "." and ".."
{
char* pDot = strrchr(pCdeFileInfo->strFileName, '.');
if (pDot)
lenName = pDot - pCdeFileInfo->strFileName;
else
lenName = (size_t)-1LL;
}
else
lenName = (size_t)-1LL; // doesn't include ".EXT". ".EXT" not existant
fFilEXTLess = (size_t)-1LL == lenName;
//printf("fFilEXTLess %d, fPatEXTLess %d\n", fFilEXTLess, fPatEXTLess);
}
//
// check match for filenNAME/SearchPatNAME and filenEXT/SearchPatEXT
//
if ( false == fFilEXTLess
&& false == fPatEXTLess) // if ".EXT" present, check ".EXT" first
{
if (NULL == __cdeStrMatch(
&pCdeFileInfo->strFileName[lenName + 1],
(size_t)-1LL, // always unlimited until '\0'
pcdeFindFirstNextData->pstrSearchPatEXT
))
continue;
}
if (true == fFilEXTLess)
if (false == fPatEXTLess)
if ('*' != *pcdeFindFirstNextData->pstrSearchPatEXT)
continue;
if (false == fFilEXTLess
&& true == fPatEXTLess)
continue;
if (NULL != __cdeStrMatch(
pCdeFileInfo->strFileName,
lenName,
pcdeFindFirstNextData->pstrSearchPatNAME
)
)
{
pFindData->attrib = pCdeFileInfo->attrib;
pFindData->size = pCdeFileInfo->attrib & _A_SUBDIR ? 0 : (_fsize_t)pCdeFileInfo->size;
pFindData->time_write = pCdeFileInfo->time_write;
pFindData->time_access = -1LL;
pFindData->time_create = -1LL;
strcpy(pFindData->name, pCdeFileInfo->strFileName);
pCdeFileInfo->attrib |= _A_CDE_EXTENSION_DONE; // mark entry done
nRet = 0; // return "found"
break;
}
}
} while (0);
return nRet;
}